<?php
/**
 * Things to keep track of 
 * file length
 * column length
 * read line for line so as to prevent hanging of the computer or sending of exceptions.
 * explode each line read such that an array is created from the read line.
 * 
 * use fread to read the document line by line
 * 
 * fgets will create a string that will automatically truncate the first time it encounters \n
 */


/**
 * @author Kartik
 * @params string file_name
 * @throws Exception (file does not exist/ file cannot be read)
 * @returns Boolean success
 *
 *	This file basically allows the user to upload a text file to the mysql server
 */
class Doctrine_Model_Upload{
	
	/**
	 * Exception messages go here
	 */
	const FILE_NOT_FOUND = "Given file could not be found ";
	const FILE_UNREADABLE = "Given file could not be read ";
	const MISSING_FILENAME = "File name was not given ";
	
	
	/**
	 * @var string /path/to/file/filename.extension
	 */
	protected $_file;
	/**
	 * @var integer line_size
	 */
	protected $_lineSize;
	
	/**
	 * @var integer file_size
	 */
	protected $_fileSize;
	
	/**
	 * @var integer total_number_of_columns
	 */
	protected $_col = 0;
	/**
	 * @var array() string_position
	 * keeps track of various string positions used in the upload file
	 */
	protected $_strPos = array();
	
	/**
	 * @var string_array column_names
	 */
	protected $_colName = array();
	
	/**
	 * @var string_multidim_array column_values
	 */
	protected $_colValue = array(array());
	
	/**
	 * @param string $file
	 * @param string $fileLoc
	 */
	public function __construct($file, $fileLoc = null){
		
		if(null == $file){
			throw new Zend_Exception(self::MISSING_FILENAME);
		}
		
		if(null == $fileLoc){
			$fileLoc = APPLICATION_PATH . '/../uploads/';
		}
		
		$this->_file = $fileLoc . $file;
		
		$fd = fopen ($fileLoc . $file, "r");
		
		if(!$fd){
			throw new Zend_Exception(self::FILE_UNREADABLE);
		}
		
		$this->_fileSize = filesize($fileLoc . $file);
		
		$colHeader = fgets($fd);
		$this->_lineSize = strlen($colHeader);

		
		fseek($fd, $this->_lineSize);
		$colHeader = fgets($fd);
		
		//calculates the field lengths for each of the columns in a given file
   		// the number of columns is also calculated on the fly.
   		for($length = 0; $length < $this->_lineSize - 2; $length += ($this->_strPos[$this->_col] + 1), $this->_col++){
   			$this->_strPos[$this->_col] = stripos(substr($colHeader, $length), " ");   				
   		}
	
   		rewind($fd);
   		$colHeader = fgets($fd);

   		//creates an array for the columns names
   		$length = 0;
   		foreach($this->_strPos as $key => $value){
   			 $this->_colName[$key] =  trim(substr($colHeader, $length, $value));
   			 $length += $value+1;
   		}
   		
		fclose ($fd); 
		
		$this->_col = count($this->_colName);
	}

	/**
	 * truncates the mbs_books table in database 
	 */
	public function clearDatabaseTable(){
		$doctrine = Doctrine_Manager::getInstance()->getCurrentConnection()->getDbh();
		$doctrine->query('TRUNCATE TABLE mbs_list');
		unset($doctrine);
	}
	
	/**
	 * adds the contents of the file to mbs_books table in database
	 */
	public function saveDatabaseTable($start, $end){
		
		if(($this->_fileSize/$this->_lineSize) < $start)
			return false;
		
		if($start < 2)
			$start = 2;
			
		if(($end - $start) > 1000)
			$end = $start + 1000;
			
		if(($this->_fileSize/$this->_lineSize) < $end)
			$end = ($this->_fileSize/$this->_lineSize);
			
		$fd = fopen($this->_file, "r");
		
		for($row = $start; $row < $end; $row++){
			fseek($fd, $row * $this->_lineSize);
			$line = fgets($fd);
			
			$q = new Doctrine_Model_MbsList();
			
			$length = 0;
			for($col = 0; $col < $this->_col; $col++){
				switch($this->_colName[$col]){
					case 'ISBN':
						$index = 'isbn13';
						break;
					case 'Author':
						$index = 'authors';
						break;
					case 'Title':
						$index = 'title';
						break;
					case 'Publisher':
						$index = 'publisher';
						break;
					case 'Binding':
						$index = 'binding';
						break;
					case 'EdYr':
						if(preg_match("/[A-Z]{2} /", (trim(substr($line, $length, $this->_strPos[$col]))))){
							list($edition, $pubYear) = preg_split("/[A-Z]{2} /", trim(substr($line, $length, $this->_strPos[$col])));
						}else{
							$edition = null;
							$pubYear = (trim(substr($line, $length, $this->_strPos[$col])));
						}
						
						break;
					case 'GuidePrice':
						$index = 'guide_price';
						break;
					case 'ActivityCode':
						$index = 'activity_code';
						break;
				}
				if(isset($index)){
					if('EdYr' == $this->_colName[$col]){
						$q['edition'] = $edition;
						$q['pubYear'] = $pubYear;
					}else{
						$q[$index] = trim(substr($line, $length, $this->_strPos[$col]));
					}
				}
				$length += $this->_strPos[$col]+1;
			}
			$q->save();
		}
	}
}